
package com.movisol.messenger.views;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.InputType;
import android.util.Base64;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager.LayoutParams;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.movisol.messenger.R;
import com.movisol.messenger.controllers.MessengerController;
import com.movisol.messenger.cropimage.CropImage;
import com.movisol.messenger.helper.MessengerHelper;
import com.movisol.messenger.views.controls.ProfileDataRow;
import com.movisol.messenger.views.controls.Separator;
import com.movisol.messengerprofileservice.data.UserProfile;
import com.movisol.messengerprofileservice.events.DataLoadedEvent;
import com.movisol.messengerprofileservice.helpers.MessengerProfileHelper;
import com.movisol.messengerprofileservice.listeners.IUserProfileDataLoadedListener;
import com.movisol.tools.HelperUtils;

/**
 * Profile that shows the information about the current logged user
 * 
 * @author Antonio Santiago
 */
public class ProfilePage extends Activity implements IUserProfileDataLoadedListener, OnClickListener
{

	private final MessengerController mc = MessengerController.getInstance();

	private Context context;

	private ImageView profilePicture;

	protected static final int PICK_FROM_CAMERA = 0;

	protected static final int PICK_FROM_GALLERY = 1;

	private static final int CROPING_FROM_CAMERA = 2;

	private String absoulutePath;

	private ImageButton imBtnLogOut;

	protected static final int outputX = 90;

	protected static final int outputY = 90;

	protected static final int aspectX = 1;

	protected static final int aspectY = 1;

	protected static final boolean return_data = true;

	private String label;

	private ProfileDataRow pdrNickname;

	private ProfileDataRow pdrFname;

	private ProfileDataRow pdrLname;

	private ProfileDataRow pdrGender;

	private ProfileDataRow pdrBirthdate;

	private LinearLayout dataLayout;

	private Drawable d;

	private DatePickerDialog editDate;

	private Uri mImageCaptureUri;

	private String tempPhotoFile;

	private boolean me = false;

	private boolean unknowContact = false;

	private UserProfile user;

	private AlertDialog ad;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.profilepage);
		getWindow().setFormat(PixelFormat.RGBA_8888);
		getWindow().addFlags(LayoutParams.FLAG_DITHER);

		mc.setCurrentPage(MessengerController.PROFILE_PAGE);
		context = mc.getContext();
		if (getIntent().getExtras() != null)
		{
			me = getIntent().getExtras().getBoolean("me");
			unknowContact = getIntent().getExtras().getBoolean("unknowContact");

		}
		initializeGUI();
	}

	private void initializeGUI()
	{
		profilePicture = (ImageView) findViewById(R.id.profilePicture);
		dataLayout = (LinearLayout) findViewById(R.id.PpDataLayout);
		imBtnLogOut = (ImageButton) findViewById(R.id.imBtnLogOut);
		imBtnLogOut.setOnClickListener(new OnClickListener()
		{

			@Override
			public void onClick(View v)
			{
				if (unknowContact)
				{
					showSendInvitation();
				} else
				{
					MessengerHelper.saveEmail(context, null);
					mc.setLoaded(false);
					mc.setDataLoaded(false);
					setResult(-1);
					finish();
				}

			}
		});

		// Hide the LogOut button for everybody but me
		if (!me)
			imBtnLogOut.setVisibility(View.INVISIBLE);

		// Change the logOut button for the AddContact image with unkown
		// contacts
		if (unknowContact)
		{
			imBtnLogOut.setVisibility(View.VISIBLE);
			imBtnLogOut.setImageResource(HelperUtils.getDrawableResource("ic_add_unknowcontact_btn", context));
		}

		tempPhotoFile = mc.pc.getUserProfile().getEmail() + "_pic_profile.jpg";

		refreshContactData();

	}

	private void showSendInvitation()
	{

		final TextView email = new TextView(context);
		email.setText(user.getEmail());
		email.setGravity(Gravity.CENTER);
		email.setTextSize(16);
		email.setPadding(0, 5, 0, 5);

		ad = new AlertDialog.Builder(this).setTitle("Send an invitation to:").setView(email)
				.setPositiveButton("Send", new DialogInterface.OnClickListener()
				{

					@Override
					public void onClick(DialogInterface dialog, int which)
					{

						List<String> emailList = new ArrayList<String>();
						emailList.add(email.getText().toString());
						mc.resendInvitation(emailList);
						ad.dismiss();
					}
				}).setNegativeButton("Cancel", new DialogInterface.OnClickListener()
				{

					@Override
					public void onClick(DialogInterface dialog, int which)
					{
						ad.dismiss();
					}
				}).show();
	}


	@Override
	protected void onResume()
	{
		// TODO Auto-generated method stub
		super.onResume();
		mc.pc.addUserProfileDataLoadedListener(this);
	}


	@Override
	protected void onStop()
	{
		// TODO Auto-generated method stub
		super.onStop();
		mc.pc.removeUserProfileDataLoadedListener(this);
		if (!isFinishing())
			finish();
	}


	@Override
	protected Dialog onCreateDialog(int id)
	{
		switch (id)
		{
		case 0:
			return editDate;
		}
		return null;
	}


	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		super.onActivityResult(requestCode, resultCode, data);

		switch (requestCode)
		{

		case PICK_FROM_CAMERA:
			Intent intent = new Intent(this, CropImage.class);
			// here you have to pass absolute path to your file
			intent.putExtra("image-path", absoulutePath);
			intent.putExtra("aspectX", aspectX);
			intent.putExtra("aspectY", aspectY);
			intent.putExtra("outputX", outputX);
			intent.putExtra("outputY", outputY);
			intent.putExtra("scale", true);
			startActivityForResult(intent, CROPING_FROM_CAMERA);
			break;

		case PICK_FROM_GALLERY:
			if (data == null)
			{

				return;
			}

			final Bundle extras = data.getExtras();
			if (extras != null)
			{
				Bitmap photo = (Bitmap) extras.getParcelable("data");

				if (photo != null && (photo.getWidth() <= outputX && photo.getHeight() <= outputY))
				{
					ByteArrayOutputStream baos = saveToFile(photo);
					String base64picture = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
					UserProfile up = new UserProfile();
					up.setPictureRaw(base64picture);

					mc.saveUserProfile(up);
				}
			}

			break;

		case CROPING_FROM_CAMERA:
			Bitmap bMap = BitmapFactory.decodeFile(absoulutePath);
			if (bMap != null && (bMap.getWidth() <= outputX && bMap.getHeight() <= outputY))
			{
				ByteArrayOutputStream baos = saveToFile(bMap);
				String base64picture = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
				UserProfile up = new UserProfile();
				up.setPictureRaw(base64picture);

				mc.saveUserProfile(up);
			}
			break;

		}
	}

	private ByteArrayOutputStream saveToFile(Bitmap bm)
	{
		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
		bm.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
		FileOutputStream fo = null;
		try
		{
			// write the bytes in file
			fo = new FileOutputStream(absoulutePath);
			fo.write(bytes.toByteArray());
		} catch (FileNotFoundException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally
		{
			if (fo != null)
				try
				{
					fo.close();
				} catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		return bytes;
	}

	private void refreshContactData()
	{

		if (me)
			user = mc.pc.getUserProfile();
		else
			user = mc.pc.getTmpUserProfile();

		if (user != null)
		{
			dataLayout.removeAllViews();

			dataLayout.addView(new Separator(context, null));

			String data = "<NOT SET>";
			if (me)
			{
				if (user.getNickName() != null && !user.getNickName().trim().equals(""))
					data = user.getCalculatedNickName();
			} else
				data = user.getCalculatedNickName();

			pdrNickname = new ProfileDataRow(context, data, "NickName");
			if (me)
				pdrNickname.setOnClickListener(this);
			dataLayout.addView(pdrNickname);

			data = "<NOT SET>";
			if (user.getFirstName() != null && !user.getFirstName().trim().equals(""))
				data = user.getFirstName();

			pdrFname = new ProfileDataRow(context, data, "First Name");
			if (me)
				pdrFname.setOnClickListener(this);
			dataLayout.addView(pdrFname);

			data = "<NOT SET>";
			if (user.getLastName() != null && !user.getLastName().trim().equals(""))
				data = user.getLastName();

			pdrLname = new ProfileDataRow(context, data, "Last Name");
			if (me)
				pdrLname.setOnClickListener(this);
			dataLayout.addView(pdrLname);

			int gender = 0;
			if (user.getGender() != null && user.getGender() > 0)
				gender = user.getGender();

			pdrGender = new ProfileDataRow(context, MessengerProfileHelper.getStringGender(gender), "Gender");
			if (me)
				pdrGender.setOnClickListener(this);
			dataLayout.addView(pdrGender);

			Date birthdate = new Date();
			if (user.getBirthdate() != null)
				birthdate = user.getBirthdate();

			SimpleDateFormat sdf = new SimpleDateFormat("dd MMMM yyyy");
			pdrBirthdate = new ProfileDataRow(context, sdf.format(birthdate), "Birthdate");
			if (me)
				pdrBirthdate.setOnClickListener(this);
			dataLayout.addView(pdrBirthdate);

			if (me)
				profilePicture.setOnClickListener(this);
			if (user.getPictureUrl() != null)
			{

				Runnable r = new Runnable()
				{

					@Override
					public void run()
					{
						Bitmap b = MessengerHelper.downloadBitmap(user.getPictureUrl());
						if (b != null)
						{
							d = new BitmapDrawable(context.getResources(), HelperUtils.getRoundedCornerBitmap(b, 10));
							profilePicture.setBackgroundDrawable(d);
						} else
						{
							// profilePicture.setBackgroundDrawable(d);
						}

					}
				};

				Thread t = new Thread(r);
				t.setPriority(Thread.MAX_PRIORITY);
				t.run();

			}
		}
	}

	@Override
	public void userProfileDataLoaded(DataLoadedEvent evt)
	{

		if (evt.getError() == null)
		{
			refreshContactData();
			if (absoulutePath != null)
			{
				File f = new File(absoulutePath);
				if (f.exists())
					f.delete();
			}
		} else
			refreshContactData();
	}

	@Override
	public void onClick(View view)
	{

		if (view.equals(pdrNickname))
		{
			final EditText editNickName = new EditText(context);
			editNickName.setInputType(InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE);
			editNickName.setText(mc.pc.getUserProfile().getNickName());

			new AlertDialog.Builder(this).setTitle("NickName").setView(editNickName)
					.setPositiveButton("Ok", new DialogInterface.OnClickListener()
					{

						@Override
						public void onClick(DialogInterface dialog, int whichButton)
						{
							label = editNickName.getText().toString();
							UserProfile up = new UserProfile();
							up.setNickName(label);
							pdrNickname.getDataTv().setText(label.equals("") ? "<NOT SET>" : label);
							mc.saveUserProfile(up);
						}
					}).setNegativeButton("Cancel", new DialogInterface.OnClickListener()
					{

						@Override
						public void onClick(DialogInterface dialog, int whichButton)
						{
							// Do nothing.
						}
					}).show();
		}

		if (view.equals(pdrFname))
		{
			final EditText editFname = new EditText(context);
			editFname.setText(mc.pc.getUserProfile().getFirstName());

			new AlertDialog.Builder(this).setTitle("First Name").setView(editFname)
					.setPositiveButton("Ok", new DialogInterface.OnClickListener()
					{

						@Override
						public void onClick(DialogInterface dialog, int whichButton)
						{
							label = editFname.getText().toString();
							pdrFname.getDataTv().setText(label);
							UserProfile up = new UserProfile();
							up.setFirstName(label);
							mc.saveUserProfile(up);
						}
					}).setNegativeButton("Cancel", new DialogInterface.OnClickListener()
					{

						@Override
						public void onClick(DialogInterface dialog, int whichButton)
						{
							// Do nothing.
						}
					}).show();
		}

		if (view.equals(pdrLname))
		{
			final EditText editLname = new EditText(context);
			editLname.setText(mc.pc.getUserProfile().getLastName());
			new AlertDialog.Builder(this).setTitle("Last Name").setView(editLname)
					.setPositiveButton("Ok", new DialogInterface.OnClickListener()
					{

						@Override
						public void onClick(DialogInterface dialog, int whichButton)
						{
							label = editLname.getText().toString();
							pdrLname.getDataTv().setText(label);
							UserProfile up = new UserProfile();
							up.setLastName(label);
							mc.saveUserProfile(up);
						}
					}).setNegativeButton("Cancel", new DialogInterface.OnClickListener()
					{

						@Override
						public void onClick(DialogInterface dialog, int whichButton)
						{
							// Do nothing.
						}
					}).show();

		}

		if (view.equals(pdrBirthdate))
		{
			Date date = mc.pc.getUserProfile().getBirthdate();
			OnDateSetListener odl = new DatePickerDialog.OnDateSetListener()
			{

				@Override
				public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)
				{
					Date date = new Date(year - 1900, monthOfYear, dayOfMonth);
					SimpleDateFormat sdf = new SimpleDateFormat("dd MMMM yyyy");
					pdrBirthdate.getDataTv().setText(sdf.format(date));
					UserProfile up = new UserProfile();
					up.setBirthdate(date);
					mc.saveUserProfile(up);

				}
			};
			if (date != null)
				editDate = new DatePickerDialog(this, odl, date.getYear() + 1900, date.getMonth(), date.getDate());
			else
			{
				Calendar c = Calendar.getInstance();
				editDate = new DatePickerDialog(this, odl, c.get(Calendar.YEAR), c.get(Calendar.MONTH),
						c.get(Calendar.DAY_OF_MONTH));
			}

			showDialog(0);

		}

		if (view.equals(pdrGender))
		{
			final CharSequence[] items =
			{ "Female", "Male" };

			new AlertDialog.Builder(this).setTitle("Gender").setItems(items, new DialogInterface.OnClickListener()
			{

				@Override
				public void onClick(DialogInterface dialog, int item)
				{
					pdrGender.getDataTv().setText(items[item].toString());
					UserProfile up = new UserProfile();
					up.setGender(item + 1);
					mc.saveUserProfile(up);
				}
			}).show();

		}

		mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), tempPhotoFile));
		absoulutePath = mImageCaptureUri.getPath();

		if (view.equals(profilePicture))
		{
			final CharSequence[] chooses =
			{ "Gallery", "Camera" };

			new AlertDialog.Builder(this).setTitle("Picture from...")
					.setItems(chooses, new DialogInterface.OnClickListener()
					{

						@Override
						public void onClick(DialogInterface dialog, int item)
						{
							switch (item)
							{
							case 0: // GALLERY
								try
								{
									// Launch picker to choose photo for
									// selected contact
									Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
									intent.setType("image/*");
									intent.putExtra("crop", "true");
									intent.putExtra("aspectX", aspectX);
									intent.putExtra("aspectY", aspectY);
									intent.putExtra("outputX", outputX);
									intent.putExtra("outputY", outputY);
									// intent.putExtra("scale", scale);
									intent.putExtra("return-data", return_data);
									intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);

									startActivityForResult(intent, PICK_FROM_GALLERY);
								} catch (ActivityNotFoundException e)
								{
									Toast.makeText(context, "error", Toast.LENGTH_LONG).show();
								}
								break;

							case 1: // CAMERA

								Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
								intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);

								try
								{
									intent.putExtra("return-data", true);
									startActivityForResult(intent, PICK_FROM_CAMERA);
								} catch (ActivityNotFoundException e)
								{
									e.printStackTrace();
								}

								break;
							}

						}
					}).show();

		}

	}

}
